#!/usr/bin/env python
import re
import urllib2

import exceptions

_ubiqis_delim = 'ubiq'

def decode_chunk(encoded):
    if len(encoded) == 0:
        raise exceptions.InvalidPackageName()

    def _fix_m(m):
        specials = {
            '_': '_',
            'h': '-',
            'p': '%',
            't': '~',
        }

        t = m.group(1)
        if t in specials:
            retval = specials[t]
        else:
            retval = t[1:].decode('hex')
        return retval

    decoded = re.sub('_(x[0-9a-fA-F]{2}|[_hpt])', _fix_m, encoded)

    return decoded

# really lazy (probably incomplete) translator
def pkg2url(pkgname):
    # package name: edu.lsu.cct.www.ubiq3._tmeastman.hello.v1
    # http://www.cct.lsu.edu/~meastman/hello/v1.ubiq

    pre = []
    post = []
    count = None

    for piece in pkgname.split('.'):
        if count is None:
            # TODO(meastman): add support for alternate protocol / port
            if piece.startswith(_ubiqis_delim) and piece[len(_ubiqis_delim):].isdigit():
                count = int(piece[len(_ubiqis_delim):])
            else:
                pre.append(decode_chunk(piece))
        else:
            post.append(decode_chunk(piece))

    if count is None or len(post) != count:
        raise exceptions.InvalidPackageName()

    if len(pre) > 1 and pre[-1].startswith(':') and pre[-1][1:].isdigit():
        port_s = pre.pop(-1)[1:]
        pre[-1] += ':' + port_s

    hostname = '.'.join(pre[::-1])
    poststr = '/'.join(post)

    return 'http://%s/%s.ubiq' % (hostname, poststr)

def expand_latest(pkg):
    pieces = pkg.split('.')
    if 'latest' in pieces:
        url = pkg2url(pkg)
        try:
            ver = urllib2.urlopen(url).read().strip()
        except Exception:
            raise exceptions.InvalidPackageName()

        pieces[pieces.index('latest')] = ver
        pkg = '.'.join(pieces)

    return pkg

